package com.quad.innovators.salesease.handler;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler;
import com.quad.innovators.salesease.annotation.DataPermission;
import com.quad.innovators.salesease.cache.SysRoleDataPermissionCache;
import com.quad.innovators.salesease.common.utils.SecurityUtils;
import com.quad.innovators.salesease.constants.SecurityConstants;
import com.quad.innovators.salesease.context.DataPermissionContextHolder;
import com.quad.innovators.salesease.context.UserContext;
import com.quad.innovators.salesease.enums.DataScopeEnum;
import com.quad.innovators.salesease.enums.IBaseEnum;
import com.quad.innovators.salesease.model.dto.SysUserAuthInfo;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 数据权限控制器
 *
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class CustomDataPermissionHandler implements DataPermissionHandler {

    private final SysRoleDataPermissionCache sysRoleDataPermissionCache;

    @Override
    @SneakyThrows
    public Expression getSqlSegment(Expression where, String mappedStatementId) {
        DataPermission dataPermission = DataPermissionContextHolder.get();
        // 如果没有注解，直接返回
        if (dataPermission == null) {
            return where;
        }
        // 获取当前用户的数据权限,获取权限码和用户对应的权限
        SysUserAuthInfo currentUser = UserContext.getCurrentUser();
        Set<String> roleSet = currentUser.getRoles().stream().map(it -> SecurityConstants.ROLE_DATA_PERMS_PREFIX + it).collect(Collectors.toSet());
        List<Map<String, Integer>> roleData = sysRoleDataPermissionCache.multiGet(roleSet);
        return dataScopeFilter(dataPermission.permissionCode(),dataPermission.userAlias(), dataPermission.userIdColumnName(), roleData, where);
    }


    /**
     * 构建过滤条件
     *
     * @param where 当前查询条件
     * @return 构建后查询条件
     */
    @SneakyThrows
    public static Expression dataScopeFilter(String permissionCode, String userAlias, String userIdColumnName, List<Map<String, Integer>> roleData,Expression where) {
        String userColumnName = StrUtil.isNotBlank(userAlias) ? (userAlias + StringPool.DOT + userIdColumnName) : userIdColumnName;
        Integer dataPermissions = SecurityUtils.getDataPermissions(permissionCode, roleData);
        DataScopeEnum dataScopeEnum = IBaseEnum.getEnumByValue(dataPermissions, DataScopeEnum.class);
        // 权限为空，默认返回全部
        if(dataScopeEnum ==null){
            return where;
        }
        Long userId;
        String appendSqlStr = null;
        switch (dataScopeEnum) {
            case ALL:
                return where;
            case SELF:
                userId = SecurityUtils.getUserId();
                appendSqlStr = userColumnName + StringPool.EQUALS + userId;
                break;
        }

        if (StrUtil.isBlank(appendSqlStr)) {
            return where;
        }
        Expression appendExpression = CCJSqlParserUtil.parseCondExpression(appendSqlStr);
        if (where == null) {
            return appendExpression;
        }
        return new AndExpression(where, appendExpression);
    }
}

